# encoding:utf-8

import os.path as osp
import sys

sys.path.append('./Lexical_analysis')

from utils import COND, STATE, STOP_LIST, getCond, stateTbale, getToken, rollBackList, OP_LOOKUP, KEYWORD_LOOKUP, \
    SE_LOOKUP

def reverse_ouput(tokens):
    length = len(tokens)
    rtokens = []
    for token in tokens:
        if isinstance(token[1], int):  # 就是说输出是关键字的标号
            index = token[1] - 1  # lookup 中的下标
            if token[0] == 'OP':
                tmp3 = OP_LOOKUP[index][0]
            elif token[0] == 'KW':
                tmp3 = KEYWORD_LOOKUP[index][0]
                if tmp3 == 'GROUP' or tmp3 == 'ORDER':
                    tmp3 += 'BY'
            elif token[0] == 'SE':
                tmp3 = SE_LOOKUP[index][0]
        else:  # 输出的不是关键字标号，而是字符串本身
            if token[0] == 'STR':  # 格式化字符串
                tmp3 = token[1][1:-1]
            else:
                tmp3 = token[1]

        #rtokens.append((tmp3, tmp2))
    return list(rtokens)


def lexicalAnalysis(string:str):
        tokens = []
        if string[-1] == ';':  # 处理可能出现的句子末尾带有#的情况
            string = string[:-1]
        if string[-1] == '\n':
            string = string[:-1]
        if (string[-1] != ' '):  # 让句子末尾带上空格符号
            string += ' '

        index = 0  # 指向下标id
        while (1):  # 一次循环输出一个类别
            if (index >= len(string) - 1):
                break
            state = STATE.S  # 每次循环开始，都处于初态
            startIndex = index  # 字符开始位置与字符结束位置形成一个字符
            while (state not in STOP_LIST):
                char = string[index]
                cond = getCond(char)  # 获取输入当前字符以后的状态
                assert (state != STATE.ERROR)

                # ----非终结状态----
                stateDict = stateTbale[state]  # 获取当前状态可用的转移
                if cond in stateDict.keys():  # 当前输入可以匹配状态
                    state = stateDict[cond]  # 状态转移
                    index += 1  # 字符串序号 +1
                else:  # 后续出现错误模式
                    print("syntax error at:", string[startIndex:])
                    assert (False)

            assert (state in STOP_LIST)
            if state in rollBackList:
                index -= 1
            value = string[startIndex:index]
            while value[0] == ' ':
                value = value[1:]
            token, updateIndex = getToken(state, value, string[index:])
            index += updateIndex
            if value == 'ORDER' or value == 'GROUP':
                value += ' BY'
            if token[0] in ['KW', 'OP']:  
                value = value.upper()
            tokens.append((value, token[0], token[1]))
        return tokens
